﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace RTF2XML
{
    public class FontFormatControl : Control
    {
        #region Private Variables
        /// <summary>
        /// Parsed control text maching the list
        /// </summary>
        private string sControl = "";

        /// <summary>
        /// Input control text
        /// </summary>
        private string sControlText = "";

        /// <summary>
        /// Number following a numbered control
        /// </summary>
        private int iNumberedControlNum = -1;
        #endregion

        #region Lists of Controls
        public static new List<string> lstControls = new List<string>()
        {
            "plain", "accnone", "accdot", "acccomma", "acccircle", "accunderdot", "b", "b0", "caps", "caps0",
            "g", "gridtbl", "embo", "embo0", "i", "i0", "impr", "impr0", "ltrch", "noproof", "nosupersub", "nosectexpand", "rtlch", "outl",
            "outl0", "scaps", "scaps0", "shad", "shad0", "strike", "strike0", "striked1", "striked0", "sub", "super", "ul", "ul0", "uld",
            "uld0", "uldash", "uldashd", "uldashd0", "uldashdd", "uldashdd0", "uldb", "uldb0", "ulhwave", "ulhwave0", "ulldash", "ulldash0",
            "ulnone", "ulth", "ulth0", "ulthd", "ulthd0", "ulthdash", "ulthdash0", "ulthdashd", "ulthdashd0", "ulthdashdd", "ulthdashdd0",
            "ulthldash", "ulthldash0", "ululdbwave", "ululdbwave0", "ulw", "ulw0", "ulwave", "ulwave0", "v", "v0", "webhidden",
            "fnil", "froman", "fswiss", "fmodern", "fscript", "fdecor", "ftech", "fbidi",
            "flomajor", "fhimajor", "fdbmajor", "fbimajor", "flominor", "fhiminor", "fdbminor", "fbiminor"
        };

        public static new List<string> lstNumberedControls = new List<string>()
        {
            "animtext", "cb", "cchs", "cf", "charscalex", "cgrid", "gcw", "dn", "expnd", "expndtw", "fittext", "f", "fs", "fprq", "fbias", "fcharset", "kerning", "langfe",
            "langfenp", "lang", "langnp", "ulc", "up"
        };

        public static new List<string> lstDestinationControls = new List<string>()
        {
            "fonttbl", "panose", "themedata"
        };
        #endregion

        /// <summary>
        /// Creates a new font format control with the given control text
        /// </summary>
        /// <param name="controlText"></param>
        public FontFormatControl(string controlText)
        {
            //Uncomment below line if you want to keep the input text (for debugging)
            //this.sControlText = controlText;
            
            //If the control is a regular control
            if(lstControls.Contains(controlText))
            {
                this.sControl = controlText;
            }
            //If the control is a destination control
            else if (lstDestinationControls.Contains(controlText))
            {
                this.sControl = controlText;
                base.bDestination = true;
            }
            //Check to see if control is a numbered control
            else
            {
                foreach (string control in lstNumberedControls)
                {
                    //If the input text starts with the control
                    if (controlText.StartsWith(control))
                    {
                        //Try to parse out the number from the input
                        string number = controlText.Replace(control, "");
                        int n = -1;
                        if (int.TryParse(number, out n))
                        {
                            //If you were able to parse out the number then it's a valid control
                            this.sControl = control;
                            this.iNumberedControlNum = n;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Checks to see if the input control is part of the control class
        /// </summary>
        /// <param name="sControl">control to check</param>
        /// <returns>true if control is in format control class, false otherwise</returns>
        public static bool IsPartOfControl(string sControl)
        {
            //If it's a regular control or a destination control
            if (lstControls.Contains(sControl) || lstDestinationControls.Contains(sControl))
            {
                return true;
            }

            //Check to see if it's a numbered control
            foreach (string control in lstNumberedControls)
            {
                if (sControl.StartsWith(control))
                {
                    //Check to see if the number can be parsed out of the control
                    string number = sControl.Replace(control, "");
                    int n = 0;
                    if (int.TryParse(number, out n))
                    {
                        return true;
                    }
                }
            }

            return false;
        }

        /// <summary>
        /// Adds the control to the xml parent node in sequence with the other nodes
        /// </summary>
        /// <param name="xmlParentNode"></param>
        public override void AddXML(ref XmlElement xmlParentNode)
        {
            int iSeqNum = 0;

            if (xmlParentNode.HasChildNodes)
            {
                //Get the last sequence number of the other children nodes
                string seqNum = xmlParentNode.LastChild.Attributes["seq"].Value;
                if (int.TryParse(seqNum, out iSeqNum))
                {
                    //Increment the sequence number
                    iSeqNum++;
                }
                else
                {
                    throw new Exception("Sequence number is not valid");
                }
            }

            //Add a new element for the control
            XmlElement child = xmlParentNode.OwnerDocument.CreateElement(this.sControl);
            //Add the sequence number
            child.SetAttribute("seq", iSeqNum.ToString());
            //If the control is a numbered control
            if (this.iNumberedControlNum != -1)
            {
                //Add the number as an attribute
                child.SetAttribute("number", this.iNumberedControlNum.ToString());
            }
            //Add element to the parent node
            xmlParentNode.AppendChild(child);
        }
    }
}
